package com.umakr.ax.app.service;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.umakr.ax.app.utils.SmsUtil;
import com.umakr.ax.common.mapper.SmsMapper;
import com.umakr.ax.common.model.Sms;
import com.umakr.ax.core.base.BaseService;
import com.umakr.ax.security.service.UserService;
import com.umakr.ax.utils.CacheUtil;
import com.umakr.ax.utils.CodeGenerateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author umakr
 */
@Service
public class AppSmsService  extends BaseService<SmsMapper, Sms> {

    private static final String SEND_CODE = "register.";
    private static final String SMS_RESPONSE_OK = "OK";
    private static final String SMS_RESPONSE_LIMIT = "isv.BUSINESS_LIMIT_CONTROL";
    private static final Integer ERROR_CODE = 2;

    @Autowired
    RedisTemplate<String,String> redisTemplate ;
    @Autowired
    UserService userService;

    /**
     * 发送短信验证码
     * @param phone
     * @param type 1表示用户注册 0表示修改密码 忘记密码等操作
     * @return
     */
    public Object sendPhoneVerifyCode(String phone,Integer type) {
        int errorCode = 0 ;
        String msg = "发送失败";

        boolean userExit = userService.checkUsernameExit(phone);
        if(userExit) {
            if(type == 1){
                userExit = false;
                msg = "该手机号已被注册！";
            }else{
                userExit = true;
            }
        }else{
            if(type == 1){
                userExit = true;
            }else{
                userExit = false;
                msg = "该手机号不存在！";
            }
        }

        if(userExit) {
            String verifyCode = "";
            if (CacheUtil.getCache().exists(SEND_CODE + phone)) {
                verifyCode = redisTemplate.opsForValue().get(SEND_CODE + phone);
            } else {
                verifyCode = CodeGenerateUtil.getFourDigitsPureNumVerifyCode();
            }
            SendSmsResponse sendSmsResponse = null;

            try {
                sendSmsResponse = SmsUtil.sendSms(phone, verifyCode);
                if (sendSmsResponse.getCode() != null && SMS_RESPONSE_OK.equals(sendSmsResponse.getCode())) {
                    //如果发送成功 存入redis中
                    BoundValueOperations<String, String> redisOper = redisTemplate.boundValueOps(SEND_CODE + phone);
                    redisOper.expire(5, TimeUnit.MINUTES);
                    redisOper.set(verifyCode);
                    errorCode = 1;
                    msg = "发送成功";
                } else if (sendSmsResponse.getCode() != null && SMS_RESPONSE_LIMIT.equals(sendSmsResponse
                        .getCode())) {
                    errorCode = 0;
                    msg = "验证码获取过于频繁，请稍后再试!";
                }
            } catch (ClientException e) {
                logger.debug(e);
            }
        }

        return resultMap(errorCode,msg);
    }

    /**
     * 验证短信验证码
     * @param phone
     * @param code
     * @return
     */
    public Object checkPhoneVerifyCode(String phone, String code) {
        int errorCode = 0 ;
        String msg = "验证码错误";

        errorCode = checkVerifyCode(phone,code);
        //验证成功后，移除Key
        if(errorCode == 1){
            msg = "验证码正确";
        }else if(errorCode == 0){
            msg = "验证码错误";
        }else if(errorCode == ERROR_CODE){
            msg = "验证码已失效，请重新获取验证码";
        }

        return resultMap(errorCode,msg);
    }

    /**
     * 返回 0验证码错误 1验证码正确 2验证码失效
     * @param phone
     * @param code
     * @return
     */
    public Integer checkVerifyCode(String phone, String code){
        String verifyCode = redisTemplate.opsForValue().get(SEND_CODE+phone);
        //验证成功后，移除Key
        if(verifyCode == null){
            return 2;
        }
        if(verifyCode.equals(code)){
            CacheUtil.getCache().del(SEND_CODE+phone);
            return 1;
        }else{
            return 0;
        }
    }

}
